﻿using System;
using IvyBus;
using System.Windows.Media.Media3D;

namespace DisplayInteraction1
{
    class ModelProto2 : InterfaceProto
    {
        private static Ivy bus;
        private static Boolean rightHandOpened = true;
        private static Point3D rightHandPos;
        private String adresse;
        private static bool displayReady = false;
        private static bool kinectReady = false;
        private static MainWindow window;

        enum States
        {
            LIBRE,
            REPOS,
            DESSIN
        }

        static States etat;

        public ModelProto2(String adresse, MainWindow window)
        {
            this.adresse = adresse;
            ModelProto2.window = window;
            bus = new Ivy("MODELPROTO2", "KINECT_EVENT=KINECT_CONNECTED");
            etat = States.LIBRE;
        }

        public void start()
        {
            bus.Start(this.adresse);
            bus.BindMsg("^IHM_EVENT=(.*)", viewReady);
            bus.BindMsg("^USER_EVENT=(.*)", user);
            bus.BindMsg("^HAND_RIGHT_POSITION X=(.*) Y=(.*) Z=(.*)", newRightHandPosition);
            bus.BindMsg("^HAND_RIGHT_EVENT=(.*)", rightHandEvent);
        }

        public void stop()
        {
            bus.UnbindMsg("^IHM_EVENT=(.*)");
            bus.UnbindMsg("^USER_EVENT=(.*)");
            bus.UnbindMsg("^HAND_RIGHT_POSITION X=(.*) Y=(.*) Z=(.*)");
            bus.UnbindMsg("^HAND_RIGHT_EVENT=(.*)");
            bus.SendMsg("KINECT_EVENT=USER_LOST");
            bus.SendMsg("KINECT_EVENT=KINECT_DISCONNECTED");
            displayReady = false;
            kinectReady = false;
            getReady();
            bus.Stop();
        }

        EventHandler<IvyMessageEventArgs> viewReady = new EventHandler<IvyMessageEventArgs>(t0);
        static void t0(Object o, IvyMessageEventArgs a)
        {
            switch (a.GetArguments()[0])
            {
                case "ASK_CONNECTION":
                    displayReady = true;
                    getReady();
                    send("KINECT_EVENT=KINECT_CONNECTED");
                    if (kinectReady) send("KINECT_EVENT=USER_DETECTED");
                    break;
                case "END_CONNECTION":
                    displayReady = false;
                    getReady();
                    break;
            }
        }

        EventHandler<IvyMessageEventArgs> user = new EventHandler<IvyMessageEventArgs>(t1);
        static void t1(Object o, IvyMessageEventArgs a)
        {
            switch (a.GetArguments()[0])
            {
                case "DETECTED":
                    kinectReady = true;
                    getReady();
                    send("KINECT_EVENT=USER_DETECTED");
                    break;
                case "LOST":
                    kinectReady = false;
                    getReady();
                    send("KINECT_EVENT=USER_LOST");
                    break;
            }
        }

        EventHandler<IvyMessageEventArgs> newRightHandPosition = new EventHandler<IvyMessageEventArgs>(t2);
        static void t2(Object o, IvyMessageEventArgs a)
        {
            rightHandPos = new Point3D(Double.Parse(a.GetArguments()[0]), double.Parse(a.GetArguments()[1]), double.Parse(a.GetArguments()[2]));
            switch (etat)
            {
                case States.LIBRE:
                    // Interdit
                    break;
                case States.REPOS:
                    send("KINECT_POSITION X=" + a.GetArguments()[0] + " Y=" + a.GetArguments()[1]);
                    break;
                case States.DESSIN:
                    send("KINECT_POSITION X=" + a.GetArguments()[0] + " Y=" + a.GetArguments()[1]);
                    break;
            }
            majMain();
        }

        EventHandler<IvyMessageEventArgs> rightHandEvent = new EventHandler<IvyMessageEventArgs>(t3);
        static void t3(Object o, IvyMessageEventArgs a)
        {
            String arg = a.GetArguments()[0];
            if (arg.Equals("OPENED"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        // Interdit
                        rightHandOpened = true;
                        break;
                    case States.REPOS:
                        rightHandOpened = true;
                        send("KINECT_STATE=DESSIN");
                        etat = States.DESSIN;
                        break;
                    case States.DESSIN:
                        // Interdit
                        break;
                }
            }
            else if (arg.Equals("CLOSED"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        // Interdit
                        rightHandOpened = false;
                        break;
                    case States.REPOS:
                        // Interdit
                        break;
                    case States.DESSIN:
                        rightHandOpened = false;
                        send("KINECT_STATE=REPOS");
                        etat = States.REPOS;
                        break;
                }
            }
            else if (arg.Equals("CLICK"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        // Interdit
                        break;
                    case States.REPOS:
                        etat = States.LIBRE;
                        send("KINECT_STATE=LIBRE");
                        break;
                    case States.DESSIN:
                        // Interdit
                        break;
                }
            }
            else if (arg.Equals("WAVE"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        send("KINECT_EVENT=CLEAN");
                        if (rightHandOpened)
                        {
                            send("KINECT_STATE=DESSIN");
                            etat = States.DESSIN;
                        }
                        else
                        {
                            send("KINECT_STATE=REPOS");
                            etat = States.REPOS;
                        }
                        break;
                    case States.REPOS:
                        // Interdit
                        break;
                    case States.DESSIN:
                        // Interdit
                        break;
                }
            }
        }

        private static void getReady()
        {
            window.majFeedbackConnection(displayReady, kinectReady);
        }

        private static void send(String s)
        {
            try
            {
                if (displayReady)
                {
                    bus.SendMsg(s);
                }
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine("Erreur envoir message proto2 : " + s + "\r\n" + e.Message);
            }
        }

        private static void majMain()
        {
           // if (rightHandOpened) window.majMainDroite("OPENED", (int)rightHandPos.X, (int)rightHandPos.Y);
           // else window.majMainDroite("CLOSED", (int)rightHandPos.X, (int)rightHandPos.Y);
        }
    }
}
